﻿//-----------------------------------------------------------------------
// <copyright file="UserProfile.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
//-----------------------------------------------------------------------
#region Usings
using System;
using FastNET.CleanAct.Common.Repository;
using FastNET.CleanAct.Common.Repository.Business;
using FastNET.CleanAct.Common.Repository.Interfaces.DataInterfaces.Client;
using FastNET.CleanAct.Common.Repository.Interfaces.Factories;
using FastNET.CleanAct.Common.Repository.Interfaces.Repositories.Client;
#endregion

namespace FastNET.CleanAct.Client.CleanEngineBusiness
{
    /// <summary>
    /// Business Class representing a user profile for the client
    /// </summary>
    public class UserProfile : IdentityBusinessBase<IUserProfileData, IUserProfileRepository>
    {
        #region Public CTor/DTor

        /// <summary>
        /// Initializes a new instance of the UserProfile class
        /// </summary>
        public UserProfile()
            : this(new RepositoryFactory())
        {
            Data.DateCreated = DateTime.UtcNow;
        }

        /// <summary>
        /// Initializes a new instance of the UserProfile class
        /// </summary>
        /// <param name="ID">Identity of the data to retrieve</param>
        public UserProfile(Identity ID)
            : this(new RepositoryFactory(), ID)
        {
        }

        #endregion

        #region Internal CTor/DTor

        /// <summary>
        /// Initializes a new instance of the UserProfile class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <param name="data">Data for backing the business object</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory or Data are null</exception>
        internal UserProfile(IRepositoryFactory factory, IUserProfileData data)
            : base(factory, data)
        {
        }

        /// <summary>
        /// Initializes a new instance of the UserProfile class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory is null</exception>
        internal UserProfile(IRepositoryFactory factory)
            : base(factory)
        {
        }

        /// <summary>
        /// Initializes a new instance of the UserProfile class
        /// </summary>
        /// <param name="factory">Factory for retrieving the Repository from</param>
        /// <param name="ID">Identity of the data to retrieve</param>
        /// <exception cref="ArgumentNullException">Thrown if Factory is null</exception>
        internal UserProfile(IRepositoryFactory factory, Identity ID)
            : base(factory, ID)
        {
        }

        #endregion

        #region Overrides of BusinessBase<IUserProfileData,IUserProfileRepository>

        /// <summary>
        /// Method to check whether or not the current object is valid
        /// </summary>
        /// <returns>Boolean based on the validity of the object</returns>
        public override bool IsValid()
        {
            return true;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the date the profile was created
        /// </summary>
        public DateTime DateCreated
        {
            get
            {
                return Data.DateCreated;
            }
        }

        /// <summary>
        /// Gets the date the profile was last updated
        /// </summary>
        public DateTime? DateUpdated
        {
            get
            {
                return Data.DateUpdated;
            }
        }

        /// <summary>
        /// Gets or sets the associated profile account name
        /// </summary>
        public string AccountName
        {
            get
            {
                return Data.AccountName;
            }

            set
            {
                Data.AccountName = value;
                MarkUpdated();
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Marks the last update date to the current utc date time
        /// </summary>
        public void MarkUpdated()
        {
            Data.DateUpdated = DateTime.UtcNow;
        }

        #endregion

        #region Internal Static Factory Methods

        /// <summary>
        /// Retrieves a single UserProfile by looking at the AccountName
        /// </summary>
        /// <param name="factory">RepositoryFactory to retrieve the data from</param>
        /// <param name="accountName">Account name to search by</param>
        /// <returns>UserProfile found or null if no account was found</returns>
        /// <exception cref="ArgumentNullException">Thrown if the search value is null or empty</exception>
        internal static UserProfile RetrieveByAccountName(IRepositoryFactory factory, string accountName)
        {
            IUserProfileData data = factory.GetRepository<IUserProfileRepository>().RetrieveByAccountName(accountName);
            return data == null ? null : new UserProfile(factory, data);
        }

        /// <summary>
        /// Checks to see if an UserProfile exists by the AccountName
        /// </summary>
        /// <param name="factory">RepositoryFactory to retrieve the data from</param>
        /// <param name="accountName">Account name to search by</param>
        /// <param name="ignoreID">ID of an user profile to ignore during check</param>
        /// <returns>Boolean whether or not an user profile exists in the system</returns>
        /// <exception cref="ArgumentNullException">Thrown if AccountName is null or empty</exception>
        /// <exception cref="InvalidCastException">Thrown if IgnoreID is of the wrong type for this repository</exception>
        internal static bool AccountNameExists(IRepositoryFactory factory, string accountName, Identity? ignoreID)
        {
            return factory.GetRepository<IUserProfileRepository>().AccountNameExists(accountName, ignoreID);
        }

        #endregion

        #region Public Static Factory Methods

        /// <summary>
        /// Retrieves a single UserProfile by looking at the AccountName
        /// </summary>
        /// <param name="accountName">Account name to search by</param>
        /// <returns>UserProfile found or null if no account was found</returns>
        /// <exception cref="ArgumentNullException">Thrown if the search value is null or empty</exception>
        public static UserProfile RetrieveByAccountName(string accountName)
        {
            return RetrieveByAccountName(new RepositoryFactory(), accountName);
        }

        /// <summary>
        /// Checks to see if an UserProfile exists by the AccountName
        /// </summary>
        /// <param name="accountName">Account name to search by</param>
        /// <param name="ignoreID">ID of an user profile to ignore during check</param>
        /// <returns>Boolean whether or not an user profile exists in the system</returns>
        /// <exception cref="ArgumentNullException">Thrown if AccountName is null or empty</exception>
        /// <exception cref="InvalidCastException">Thrown if IgnoreID is of the wrong type for this repository</exception>
        public static bool AccountNameExists(string accountName, Identity? ignoreID)
        {
            return AccountNameExists(new RepositoryFactory(), accountName, ignoreID);
        }

        #endregion
    }
}
